#include "Nodo.h"

Nodo::Nodo() {
    JugoNegro = false;
    estado    = state_t(6);
}

Nodo::Nodo(bool empiezaNegro) {
    JugoNegro = !empiezaNegro;
    estado    =  state_t(6);
}

Nodo::Nodo(int pos, const Nodo *nodo) {
    Set(pos, nodo);
}

void Nodo::Set(int pos, const Nodo *nodo) {
    JugoNegro = !nodo->JugoNegro;
    estado    =  nodo->estado.move(JugoNegro, pos);
}

bool Nodo::esTerminal() const{
    return estado.terminal();
}

int Nodo::Valor() const{
    return estado.value();
}

bool Nodo::juegaBlanco() const{
    return JugoNegro;
}
    
bool Nodo::juegaNegro() const{
    return !JugoNegro;
}

void Nodo::imprimir() const{
    estado.print(cout, 0);
}

Nodo::~Nodo() {
}

Nodo::Iterador::Iterador(Nodo *nodo) {
    this->nodo = nodo;
    Actual = 3;
    primerGenerado = false;
}

Nodo *Nodo::Iterador::Siguiente() {
    Nodo *hijo = new Nodo();
    if(Siguiente(hijo))
        return hijo;
    else return NULL;
}

bool Nodo::Iterador::Siguiente(Nodo *hijo) {
    bool (state_t::*is_move)(int) const;
    
    if(Actual >= DIM) return returnNodo(true, hijo);
    
    if(nodo->JugoNegro) is_move = &state_t::is_white_move;
    else                is_move = &state_t::is_black_move;
    
    state_t *st = &(nodo->estado);
    
    for(; !(st->*is_move)(Actual);)
        if(++Actual >= DIM) return returnNodo(true, hijo);
    
    return returnNodo(false, hijo);
}

inline bool Nodo::Iterador::returnNodo(bool nulo, Nodo *hijo){
    if(nulo) {
        if(primerGenerado) return false;
        hijo->Set(DIM, nodo);
        return (primerGenerado = true);
    }
     hijo->Set(Actual++, nodo);
    return (primerGenerado = true);
}

Nodo::Iterador::~Iterador() {
    
}










